package com.info.zhiduoduo.core.service.payment.thirdpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.info.zhiduoduo.common.configs.CommonConfig;
import com.info.zhiduoduo.common.configs.KltPayConfig;
import com.info.zhiduoduo.common.configs.PayConfig;
import com.info.zhiduoduo.common.configs.PayTestModeConfig;
import com.info.zhiduoduo.common.configs.ZddUrlConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.pay.ZhaoShangPayOrderState;
import com.info.zhiduoduo.common.exception.RollbackException;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.LogUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangAgentPayFormBean;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangOutlineDTO;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangPayResDTO;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangTransactionOutlineFormBean;
import com.info.zhiduoduo.core.service.WxMessageService;
import com.info.zhiduoduo.core.service.ZhiduoduoProjectService;

import com.info.zhiduoduo.repository.entity.order.TradeRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Date;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ZhaoShangPayService implements ThirdPayService {

	@Autowired
	ZhiduoduoProjectService zhiduoduoProjectService;
	@Autowired
	WxMessageService wxMessageService;
	@Autowired
	CommonConfig commonConfig;
	@Autowired
	ZddUrlConfig zddUrlConfig;
	@Autowired
	PayConfig payConfig;
	@Autowired
	KltPayConfig kltPayConfig;
	@Autowired
	PayTestModeConfig payTestModeConfig;

	@Override
	public SmartResult doCallPayApi(TradeRecord tradeRecord) {
		SmartResult smartResult = null;
		// 测试
		if (payTestModeConfig.isTestMode()) {
			// 直接支付成功
			// 等待30秒，模拟超时情况
			try {
				Thread.sleep(30000);
			} catch (InterruptedException e) {
			}
			return handlePayUserTradeState(tradeRecord, ZhaoShangPayOrderState.SUCCESS, "", "");
		} else {
			//调用第三方支付
			ZhaoShangAgentPayFormBean formBean = ZhaoShangAgentPayFormBean.of(tradeRecord);
			String url = zddUrlConfig.getBasePayUrl() + payConfig.getZhaoShangAgentPayUrl();
			LogUtil.info("支付调用 url = " + url);
			smartResult = new RestTemplate().postForObject(url, formBean, SmartResult.class);
		}
		return handleZhaoShangPayResult(tradeRecord, smartResult);
	}

	@Override
	public SmartResult handlePayUserTradeState(TradeRecord trade, String orderState, String errorcode, String errormsg) {
		if (trade == null) return SmartResult.success(StatusMsg.StatusMsg_444);
		trade.setErrorcode(errorcode).setErrormsg(errormsg);
		switch (orderState) {
			case ZhaoShangPayOrderState.SUCCESS:
				trade.setTradestate(Constants.TRADE_SUCCESS).setFinishtime(new Date());
				zhiduoduoProjectService.doAfterPayUserTradeSucceed(trade);
				break;
			case ZhaoShangPayOrderState.FAIL:
				trade.setTradestate(Constants.TRADE_FAIL).setFinishtime(new Date());
				wxMessageService.notifyAdminPaymentFail(trade);
				break;
		}
		if (trade.updateById()) return SmartResult.success();
		return SmartResult.fail(StatusMsg.StatusMsg_445);
	}

	public SmartResult handleZhaoShangPayUserTradeState(TradeRecord trade, String orderState, String errorcode, String errormsg) {
		if (trade == null) return SmartResult.success(StatusMsg.StatusMsg_444);
		trade.setErrorcode(errorcode).setErrormsg(errormsg);
		if (ZhaoShangPayOrderState.SUCCESS.equals(orderState)) {
			trade.setTradestate(Constants.TRADE_SUCCESS).setFinishtime(new Date());
			zhiduoduoProjectService.doAfterPayUserTradeSucceed(trade);
		} else if (ZhaoShangPayOrderState.FAIL.equals(orderState)) {
			trade.setTradestate(Constants.TRADE_FAIL).setFinishtime(new Date());
			wxMessageService.notifyAdminPaymentFail(trade);
		} else {
			//判断交易时间是否过了10分钟,如果超过了10分钟查询交易概要
			long differTime = DateUtil.differMinute(DateUtil.DateToStr("yyyy-MM-dd HH:mm:ss",trade.getTradetime()),DateUtil.DateToStr("yyyy-MM-dd HH:mm:ss",new Date()));
			if(10 < differTime){
				ZhaoShangTransactionOutlineFormBean formBean = ZhaoShangTransactionOutlineFormBean.of(trade.getMerchantid(),
						DateUtil.DateToStr("yyyyMMdd",trade.getTradetime()),trade.getTradeno());
				//查询交易概要
				SmartResult smartResult = new RestTemplate().postForObject(
						zddUrlConfig.getBasePayUrl() + payConfig.getZhaoShangQueryOutlineUrl(), formBean, SmartResult.class);
				if (null != smartResult.getObject() && smartResult.isSuccessful()) {
					ZhaoShangOutlineDTO outline = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), new TypeReference<ZhaoShangOutlineDTO>(){});
					//判断是不是支付失败
					if ("F".equals(outline.getRtnflg())) {
						trade.setTradestate(Constants.TRADE_FAIL).setErrormsg(outline.getErrdsp()).setFinishtime(new Date());
						wxMessageService.notifyAdminPaymentFail(trade);
					}
				}
			}
		}
		if (trade.updateById()) return SmartResult.success();
		return SmartResult.fail(StatusMsg.StatusMsg_445);
	}

	private SmartResult handleZhaoShangPayResult(TradeRecord trade, SmartResult smartResult) {
		if (null == smartResult) {
			LogUtil.info("zdd-pay没有返回smartResult");
			throw new RollbackException(" 项目,招商支付失败");
		}
		if (smartResult.getObject() == null || smartResult.isFailed()) {
			if (smartResult.getState() == StatusMsg.StatusMsg_472.state) {
				LogUtil.info("招商银行网络问题，将项目状态修改为进行中，等待后续查询结果");
				//招商银行网络错误 发送通知
				wxMessageService.tradeNetErrorNotifyAdmin();
				trade.setTradestate(Constants.TRADE_IN_PROCESS);
				if (trade.updateById()) return SmartResult.success();
			}
			//支付失败 修改支付状态
			if(smartResult.getState() == StatusMsg.StatusMsg_465.state) {
				trade.setTradestate(Constants.TRADE_FAIL).updateById();
			}
			// 返回 其他请求结果报错
			return SmartResult.fail(StatusMsg.StatusMsg_445);
		} else {
			//支付接口调用成功,查看交易结果
			ZhaoShangPayResDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), new TypeReference<ZhaoShangPayResDTO>(){});
			if (null == payResult || StringUtil.isEmpty(payResult.getReqnbr())) {
				trade.setTradestate(Constants.TRADE_FAIL).setFinishtime(new Date());
				wxMessageService.notifyAdminPaymentFail(trade);
				if (trade.updateById()) return SmartResult.success();
				return SmartResult.fail(StatusMsg.StatusMsg_445);
			} else {
				trade.setPartnerOrderNo(payResult.getReqnbr()).setTradestate(Constants.TRADE_IN_PROCESS);
				if (trade.updateById()) return SmartResult.success();
				return SmartResult.fail(StatusMsg.StatusMsg_445);
			}
		}
	}

	@Override
	public SmartResult handlePayJiugeTradeState(TradeRecord trade, String orderState, String errorcode, String errormsg) {
		return SmartResult.fail(StatusMsg.StatusMsg_445);
	}

}
